package com.oig.sys.base.controller;


import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.oig.common.exception.BadRequestException;
import com.oig.common.module.SysRequest;
import com.oig.common.module.SysResponse;
import com.oig.common.validator.GroupAdd;
import com.oig.common.validator.GroupEdit;
import com.oig.sys.base.app.IAppHarborService;
import com.oig.sys.base.dto.HarborDto;
import com.oig.sys.base.service.ITbCountryService;
import com.oig.sys.base.service.ITbHarborService;
import com.oig.sys.base.vo.CountryVo;
import com.oig.sys.base.vo.HarborVo;
import com.oig.sys.log.annotation.SysLog;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.Map;

@Tag(name = "口岸管理")
@RestController
@RequestMapping("/harbor")
@Slf4j
public class TbHarborController {

    private final IAppHarborService appHarborService;
    private final ITbHarborService harborService;
    private final ITbCountryService countryService;

    @Autowired
    public TbHarborController(IAppHarborService appHarborService,
                              ITbHarborService harborService,
                              ITbCountryService countryService){
        this.appHarborService = appHarborService;
        this.harborService = harborService;
        this.countryService = countryService;
    }

    @PreAuthorize("@pms.hasPermission('/harbor/addHarbor')")
    @SysLog(value="添加口岸",apiUrl="/harbor/addHarbor")
    @Operation(summary = "添加口岸")
    @PostMapping(value = "/addHarbor")
    public HarborVo addHarbor(@RequestBody @Validated(GroupAdd.class) HarborDto harborDto){
        log.info("add harbor {}",harborDto);
        return this.appHarborService.addTbHarbor(harborDto);
    }

    @PreAuthorize("@pms.hasPermission('/harbor/updateHarbor')")
    @SysLog(value="修改口岸",apiUrl="/harbor/updateHarbor")
    @Operation(summary = "修改口岸")
    @PostMapping(value = "/updateHarbor")
    public HarborVo updateHarbor(@RequestBody @Validated(GroupEdit.class) HarborDto harborDto){
        log.info("update harbor {}",harborDto);
        return this.appHarborService.updateTbHarbor(harborDto);
    }

    @PreAuthorize("@pms.hasPermission('/harbor/cancelHarbor')")
    @SysLog(value="逻辑删除口岸",apiUrl="/harbor/cancelHarbor")
    @Operation(summary = "逻辑删除口岸")
    @PostMapping(value = "/cancelHarbor/{id}")
    public SysResponse<Integer> cancelHarbor(@PathVariable("id") Integer id){
        log.info("cancel Harbor id={}", id) ;
        this.appHarborService.cancelTbHarbor(id);
        return SysResponse.ok(id,"逻辑删除口岸成功");
    }


    @Operation(summary = "查询备选口岸,输入选择框时使用，返回前N条记录")
    @PostMapping(value = "/findHarbor")
    public List<HarborVo> findHarbor(@RequestBody SysRequest<HarborDto> harborRequest){
        log.info("find Harbor {}", harborRequest) ;
        return this.harborService.findHarbor(harborRequest) ;
    }



    @PreAuthorize("@pms.hasPermission('/harbor/importHarbor')")
    @SysLog(value="批量导入口岸",apiUrl="/harbor/importHarbor")
    @PostMapping("/importHarbor/{countryCode}")
    @Operation(summary = "批量导入口岸,json 文件导入")
    public SysResponse<String> importHarbor(@PathVariable("countryCode") String countryCode, @RequestPart("jsonFile") MultipartFile jsonFile){
        log.info("import harbor country:{}", countryCode);
        if (jsonFile == null || jsonFile.getSize() == 0 || StrUtil.isBlank(jsonFile.getOriginalFilename())) {
            throw new BadRequestException("空文件..");
        }
        if (StringUtils.isEmpty(countryCode)){
            throw new BadRequestException("国家地区代码必填") ;
        }
        CountryVo countryVo = countryService.getCountryByCode(countryCode) ;
        if (countryVo==null){
            return SysResponse.failed("国家地区不存在");
        }
        try{
            EasyExcel.read(jsonFile.getInputStream(), new PageReadListener<Map<Integer, String>>(dataList -> {
                for (Map<Integer, String> dataMap : dataList){
                    log.debug("excel data map:{}",dataMap);
                    HarborVo harborVo = this.harborService.getByName(dataMap.get(0));
                    if (harborVo!=null){
                        log.warn("已存在口岸：{}", harborVo);
                        continue;
                    }
                    HarborDto harborDto = new HarborDto();
                    harborDto.setCode(dataMap.get(1));
                    harborDto.setName(dataMap.get(0));
                    harborDto.setCountryCode(countryVo.getCode());
                    harborDto.setCountryName(countryVo.getName());
                    this.appHarborService.addTbHarbor(harborDto);
                }
            })).headRowNumber(2).sheet().doRead();
        } catch (Exception e){
            log.error("file upload error", e);
            return SysResponse.failed("导入口岸失败");
        }
        return SysResponse.ok(jsonFile.getOriginalFilename(),"导入口岸成功");
    }




    @Operation(summary = "根据编码获取口岸")
    @PostMapping(value = "/getByCode")
    public HarborVo getByCode(@RequestParam("code") String code){
        log.info("getByCode：{}",code);
        return this.harborService.getByCode(code);
    }

    @Operation(summary = "根据名称获取口岸")
    @PostMapping(value = "/getByName")
    public HarborVo getByName(@RequestParam("name") String name){
        log.info("getByName：{}",name);
        return this.harborService.getByName(name);
    }

    @Operation(summary = "根据原code获取口岸")
    @PostMapping(value = "/getByOldCode")
    public HarborVo getByOldCode(@RequestParam("oldCode") String oldCode){
        log.info("get harbor by old code：{}",oldCode);
        return this.harborService.getByOldCode(oldCode);
    }

}
